package com.goldgov.utils;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.alibaba.fastjson.JSONObject;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.processor.PageProcessor;

/**
 * <爬虫测试工具类>
 * @author RongSL
 * @version 1.0.0
 * */
public class CrawlerUtilsTest implements PageProcessor {

	protected final Log logger = LogFactory.getLog(this.getClass());
	
	// 抓取网站的相关配置，包括编码、抓取间隔、重试次数等
	private Site site = Site.me().setRetryTimes(3).setSleepTime(10);
	private int level=1;
	private String rule;//列表地址
	private String articleUrlRule;//文章地址
	private static List<Object> resultList;

	public CrawlerUtilsTest() {
		CrawlerUtilsTest.resultList=null;
	}
	
	@Override
	public void process(Page page) {
		try {
			JSONObject json=(JSONObject) page.getRequest().getExtra("_rules");
			this.level =json.getIntValue("_level");
			this.rule=json.getString("_rule");
			this.articleUrlRule=json.getString("_articleUrlRule");
			if (judgeLevel(rule)) //根据表达式获取数据
				if (null == getRuleValueSupply(rule)) //判断是否存在补充规则
					if(rule.indexOf(",")==-1) //判断是否是链接型表打死
						getResultList().add(page.getHtml().xpath(getRuleValue(rule)).all());
					else
						getResultList().add(page.getHtml().xpath(getRuleValue(rule)).toString());
				else
					if(rule.indexOf(",")==-1) 
						getResultList().add(page.getHtml().xpath(getRuleValue(rule)).regex(getRuleValueSupply(rule)).all());
					else
						getResultList().add(page.getHtml().xpath(getRuleValue(rule)).regex(getRuleValueSupply(rule)).toString());
			
			if(null==rule) {
				throw new Exception("请填写具体规则");
			}else if(rule.split(",").length!=1&&null==articleUrlRule) {
				 throw new Exception("请填写文章地址规则");
			}else if(rule.indexOf(",")>0){
				List<String> links = page.getHtml().xpath(articleUrlRule).all();// 文章链接集合
				if(!links.isEmpty()) {
					Request requests = new Request();
					json.put("_level", this.level+1);
					requests.putExtra("_rules", json);
					requests.setUrl(getAbsoluteURL(page.getUrl().get(),links.get(0)));
					page.addTargetRequest(requests);
				}
			}
		}catch(Exception e) {
//			logger.info("========》爬虫表达式书写错误",e);
			getResultList().add("错误提示："+e.getMessage());
		}
	}

	/**
	 * 相对路径转绝对路径
	 * @param baseURI
	 * @param relativePath
	 * @version 1.0.0
	 */
	@SuppressWarnings("finally")
	public static String getAbsoluteURL(String baseURI, String relativePath){
	    String abURL=null;
	    try {
	        URI base=new URI(baseURI);//基本网页URI
	        URI abs=base.resolve(relativePath);//解析于上述网页的相对URL，得到绝对URI
	        URL absURL=abs.toURL();//转成URL
	        abURL = absURL.toString();
	    } catch (MalformedURLException e) {
	        e.printStackTrace();
	    } catch (URISyntaxException e) {
	        e.printStackTrace();
	    } finally{
	        return abURL;
	    }
	}
	
	@Override
	public Site getSite() {
		return site;
	}
	
	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public boolean judgeLevel(String str) {
		if (null == str || "" .equals(str))
			return false;
		else if(str.split(",").length==1)
			return true;
		else
			return getLevel() == Integer.valueOf(str.split(",")[0]).intValue() ? true : false;
	}

	public String getRuleValue(String str) {
		if(str.split(",").length==1)
			return str;
		return str.split(",")[1];
	}

	public String getRuleValueSupply(String str) {
		if (str.split(",").length < 3)
			return null;
		else
			return str.split(",")[2];
	}

	public String getRule() {
		return rule;
	}

	public void setRule(String rule) {
		this.rule = rule;
	}

	public static List<Object> getResultList() {
		if(null==resultList) {
			resultList=new ArrayList<>();
		}
		return resultList;
	}
}